<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>创建和插入元素(Create and Insert Elements)</title>
  <!-- 
  在JavaScript中，创建和插入元素是操作DOM的重要部分。通过创建新的HTML元素并将其插入到现有文档中.
  一、创建元素

  1. 使用 document.createElement()：
    - 这是创建新元素的标准方法。该方法接受一个字符串参数，表示要创建的元素的标签名。
    const newDiv = document.createElement('div'); // 创建一个新的 <div> 元素
    newDiv.textContent = '这是一个新创建的 div 元素'; // 设置元素的文本内容

  二、插入元素 - 创建元素后，可以通过多种方法将其插入到文档中：
    1. 使用 appendChild()：
      - appendChild() 方法将一个节点添加到指定父节点的子节点列表的末尾。
      const parentElement = document.getElementById('parent'); // 获取父元素
      parentElement.appendChild(newDiv); // 将新创建的 div 元素插入到父元素中
    2. 使用 insertBefore()：
      - insertBefore() 方法在指定的子节点之前插入一个新节点。
      const referenceNode = document.getElementById('reference'); // 获取参考节点
      parentElement.insertBefore(newDiv, referenceNode); // 在参考节点之前插入新元素
    3. 使用 replaceChild()：
      - replaceChild() 方法用一个新的子节点替换指定的旧子节点。
      const oldChild = document.getElementById('oldChild'); // 获取要替换的旧子节点
      parentElement.replaceChild(newDiv, oldChild); // 用新元素替换旧元素
    4. 使用 innerHTML：
      - 通过设置元素的 innerHTML 属性，可以直接插入HTML内容。这种方法适用于简单的插入，但要小心使用，因为它会解析HTML并可能导致安全问题（如XSS攻击）。
      parentElement.innerHTML += '<div>这是通过 innerHTML 插入的元素</div>';

  三、插入元素新方法
    1. append()：将一个或多个节点添加到指定父节点的子节点列表的末尾。
    2. prepend()：将一个或多个节点添加到指定父节点的子节点列表的开头。
    3. before()：在指定节点之前插入一个或多个节点。
    4. after()：在指定节点之后插入一个或多个节点。
    5. replaceWith()：用新的节点替换指定的节点。

  总结
  - 使用 document.createElement() 方法可以创建新的HTML元素。
  - 可以通过 appendChild()、insertBefore()、replaceChild() 等方法将新元素插入到DOM中。
  - innerHTML 属性也可以用来插入HTML内容，但需谨慎使用。

  注意: 一个元素只能有一个父元素，如果将一个元素插入到另一个元素中，它将从原来的父元素中移除，并添加到新的父元素中。除非克隆该元素，否则它将不再存在于原来的父元素中。
   -->
  <style>
    .border {
      border: 1px solid black;
    }
  </style>
</head>
<body>

  <h2>创建和插入元素(Create and Insert Elements)</h2>
  <p>注意: 一个元素只能有一个父元素，如果将一个元素插入到另一个元素中，它将从原来的父元素中移除，并添加到新的父元素中。除非克隆该元素，否则它将不再存在于原来的父元素中。</p>

  <h3>1. 使用innerHTML(不推荐) - 会覆盖父元素中所有内容</h3>
  <div class="border inner-html">
    <span class="inner-html__text">创建和插入元素</span>
    <p>创建和插入元素是操作DOM的重要部分。通过创建新的HTML元素并将其插入到现有文档中.</p>
  </div>

  <h3>2.createElement and appendChild</h3>
  <div class="border append-child">
    <span class="append-child__text">创建和插入元素</span>
    <p>创建和插入元素是操作DOM的重要部分。通过创建新的HTML元素并将其插入到现有文档中.</p>
  </div>

  <h3>3.createElement and insertBefore</h3>
  <div class="border insert-before">
    <span class="insert-before__text">创建和插入元素</span>
    <p>创建和插入元素是操作DOM的重要部分。通过创建新的HTML元素并将其插入到现有文档中.</p>
  </div>

  <h3>4.createElement</h3>
  <div class="border replace-child">
    <span class="replace-child__text">创建和插入元素</span>
    <p>创建和插入元素是操作DOM的重要部分。通过创建新的HTML元素并将其插入到现有文档中.</p>
  </div>

  <div id="oldChild" style="color: pink;">使用replaceChild() - 替换指定位置的元素</div>

  <h3>============ append/prepend/after/before/replaceWith ==============</h3>

  <h3>1.append</h3>
  <div class="border append">
    <span class="append_text">append方法</span>
    <p>将一个或多个节点添加到指定父节点的子节点列表的末尾。</p>
  </div>

  <h3>2.prepend</h3>
  <div class="border prepend">
    <span class="prepend_text">prepend方法</span>
    <p>将一个或多个节点添加到指定父节点的子节点列表的开头。</p>
  </div>

  <h3>3.before</h3>
  <div class="border before">
    <span class="before_text">before方法</span>
    <p>在指定节点之前插入一个或多个节点。</p>
  </div>

  <h3>4.after</h3>
  <div class="border after">
    <span class="after_text">after方法</span>
    <p>在指定节点之后插入一个或多个节点。</p>
  </div>

  <h3>5.replaceWith</h3>
  <div class="border replaceWith">
    <span class="replaceWith_text">replaceWith方法</span>
    <p>用新的节点替换指定的节点。</p>
  </div>
  
  <script>

    // 方案一：createElement + appendChild + innerHTML + textContent + insertBefore + replaceChild
    {
      const innerHTMLEL = document.querySelector('.inner-html');
      const appendChildEl = document.querySelector('.append-child');
      const insertBeforeEl = document.querySelector('.insert-before');
      const oldChild = document.getElementById('oldChild'); // 获取要替换的旧子节点

      // 1. 使用innerHTML(不推荐) - 会覆盖父元素中所有内容
      innerHTMLEL.innerHTML = '<p style="color: red">这是通过 innerHTML 插入的元素</p>';

      // 2. 使用createElement() - 创建新元素
      const newDiv = document.createElement('div');
      newDiv.style.color = 'red';
      newDiv.textContent = '这是通过 createElement() 创建的元素';

      // 3. 使用appendChild() - 添加到父元素的末尾
      // 克隆newDiv，因为appendChild()会移动元素
      const clonedNewDiv = newDiv.cloneNode(true);
      appendChildEl.appendChild(clonedNewDiv);

      // 4. 使用insertBefore() - 插入到指定位置
      const referenceNode = document.querySelector('.insert-before__text');
      insertBeforeEl.insertBefore(newDiv, referenceNode);

      // 5. 使用replaceChild() - 替换指定位置的元素
      const reqlaceChildTextEl = document.querySelector('.replace-child__text');
      reqlaceChildTextEl.parentNode.replaceChild(oldChild, reqlaceChildTextEl); // 用新元素替换旧元素
    }

    // 方案二: append/prepend/after/before/replaceWith 可以直接添加多个/替换元素
    // 1. append() - 添加到父元素里面的末尾
    const appendEl = document.querySelector('.append');
    const newAppendChild = document.createElement('div');
    newAppendChild.style.color = 'red';
    newAppendChild.textContent = '这是通过 append() 创建的元素';
    appendEl.append(newAppendChild);
    
    // 2. prepend() - 添加到父元素里面的开头
    const prependEl = document.querySelector('.prepend');
    const newPrependChild = document.createElement('div');
    newPrependChild.style.color = 'red';
    newPrependChild.textContent = '这是通过 prepend() 创建的元素';
    prependEl.prepend(newPrependChild);

    // 3. after() - 添加到指定元素之后
    const afterEl = document.querySelector('.after');
    const newAfterChild = document.createElement('div');
    newAfterChild.style.color = 'red';
    newAfterChild.textContent = '这是通过 after() 创建的元素';
    afterEl.after(newAfterChild);
    
    // 4. before() - 添加到指定元素之前
    const beforeEl = document.querySelector('.before');
    const newBeforeChild = document.createElement('div');
    newBeforeChild.style.color = 'red';
    newBeforeChild.textContent = '这是通过 before() 创建的元素';
    beforeEl.before(newBeforeChild);
    
    // 5. replaceWith() - 替换指定元素
    const replaceEl = document.querySelector('.replaceWith_text');
    const newReplaceChild = document.createElement('div');
    newReplaceChild.style.color = 'red';
    newReplaceChild.textContent = '这是通过 replaceWith() 创建的元素';
    replaceEl.replaceWith(newReplaceChild);
    
  </script>
  
</body>
</html>